﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace GMusicBox
{
    public partial class TrackBar : UserControl
    {
        public TrackBar()
        {
            InitializeComponent();
            Horizontal = true;
            Maximum = 10;
        }

        Point mouse_offset;
        public new event EventHandler Scroll;
        public event EventHandler ScrollEnd;
        public event EventHandler ValueChanged;

        public bool Horizontal { get; set; }
        public double Maximum { get; set; }
        public double Minimum { get; set; }
        public int MoveStep { get; set; }

        public double Value
        {
            get
            {
                if (Horizontal)
                {
                    double center = btn.Left + btn.Width / 2 - 7;
                    return center / (this.Width - 14) * (Maximum - Minimum) + (Minimum < 0 ? Minimum : 0);
                }
                else
                {
                    double center = btn.Top + btn.Height / 2 - 7;
                    return (Maximum - Minimum) - center / (this.Height - 14) * (Maximum - Minimum) + (Minimum < 0 ? Minimum : 0);
                }
            }
            set
            {
                if (Minimum < 0) value -= Minimum;
                if (Horizontal)
                    btn.Left = (int)(value / (Maximum - Minimum) * (this.Width - 14));
                else
                    btn.Top = (this.Height - 14) - (int)(value / (Maximum - Minimum) * (this.Height - 14));

                if (ValueChanged != null) ValueChanged(this, EventArgs.Empty);
                this.Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            if (Horizontal)
            {
                Rectangle client = new Rectangle(7, 5, this.Width - 15, 4);

                e.Graphics.DrawLine(new Pen(Color.FromArgb(134, 134, 134)), new Point(8, 5), new Point(this.Width - 9, 5));
                e.Graphics.DrawLine(new Pen(new LinearGradientBrush(new Point(this.Width - 8, 6), new Point(this.Width - 8, 8), Color.FromArgb(134, 134, 134), Color.FromArgb(172, 172, 172))), new Point(this.Width - 8, 6), new Point(this.Width - 8, 8));
                e.Graphics.DrawLine(new Pen(Color.FromArgb(172, 172, 172)), new Point(8, 9), new Point(this.Width - 9, 9));
                e.Graphics.DrawLine(new Pen(new LinearGradientBrush(new Point(7, 6), new Point(7, 8), Color.FromArgb(134, 134, 134), Color.FromArgb(172, 172, 172))), new Point(7, 6), new Point(7, 8));
                e.Graphics.FillRectangle(new LinearGradientBrush(client, Color.FromArgb(175, 175, 175), Color.FromArgb(210, 210, 210), LinearGradientMode.Vertical), client);

                int width = btn.Left + btn.Width / 2 - 7;
                if (width < 8) return;
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(180, 210, 241)), new Rectangle(7, 5, width + 1, 2));
                e.Graphics.DrawLine(new Pen(Color.FromArgb(102, 148, 227)), new Point(8, 8), new Point(width, 8));
            }
            else
            {
                Rectangle client = new Rectangle(4, 7, 5, this.Height - 14);

                e.Graphics.DrawLine(new Pen(Color.FromArgb(134, 134, 134)), new Point(5, 7), new Point(this.Width - 7, 7));
                e.Graphics.DrawLine(new Pen(new LinearGradientBrush(new Point(this.Width - 6, 7), new Point(this.Width - 6, this.Height - 8), Color.FromArgb(134, 134, 134), Color.FromArgb(172, 172, 172))), new Point(this.Width - 6, 7), new Point(this.Width - 6, this.Height - 8));
                e.Graphics.DrawLine(new Pen(Color.FromArgb(172, 172, 172)), new Point(5, this.Height - 7), new Point(this.Width - 7, this.Height - 7));
                e.Graphics.DrawLine(new Pen(new LinearGradientBrush(new Point(4, 7), new Point(4, this.Height - 8), Color.FromArgb(134, 134, 134), Color.FromArgb(172, 172, 172))), new Point(4, 7), new Point(4, this.Height - 8));
                e.Graphics.FillRectangle(new LinearGradientBrush(client, Color.FromArgb(175, 175, 175), Color.FromArgb(210, 210, 210), LinearGradientMode.Vertical), client);

                int height = btn.Top + btn.Height / 2 - 7;
                int height1 = (this.Height - 14) - height;
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(180, 210, 241)), new Rectangle(6, height + 7, 3, height1));
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(102, 148, 227)), new Rectangle(4, height + 7, 2, height1));
            }
        }

        private void btn_MouseDown(object sender, MouseEventArgs e)
        {
            mouse_offset = new Point(-e.X, -e.Y);
        }

        private void btn_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Control send = ((Control)sender);
                Point mousePos = Control.MousePosition;
                if (Horizontal) mousePos.Offset(mouse_offset.X, -e.Y);
                else mousePos.Offset(-e.X, mouse_offset.Y);

                Point p = send.Parent.PointToClient(mousePos);
                if (Horizontal)
                {
                    if (p.X < 0) p.X = 0;
                    else if (p.X + 14 > this.Width) p.X = this.Width - 14;

                    if (MoveStep != 0)
                    {
                        int i = (p.X - btn.Left) / MoveStep * MoveStep - (p.X - btn.Left);
                        p = new Point(p.X + i, p.Y);
                    }
                }
                else
                {
                    if (p.Y < 0) p.Y = 0;
                    else if (p.Y + 14 > this.Height) p.Y = this.Height - 14;

                    if (MoveStep != 0)
                    {
                        int i = (p.Y - btn.Top) / MoveStep * MoveStep - (p.Y - btn.Top);
                        p = new Point(p.X, p.Y + i);
                    }
                }
                btn.Location = p;

                if (Scroll != null) Scroll(this, EventArgs.Empty);
                if (ValueChanged != null) ValueChanged(this, EventArgs.Empty);

                this.Invalidate();
            } 
        }

        private void btn_MouseUp(object sender, MouseEventArgs e)
        {
            if (ScrollEnd != null) ScrollEnd(this, EventArgs.Empty);
        }
    }
}
